"use strict";

// 控制是否打印废弃警告stderr。将其设置为true将消除弃用警告。
process.noDeprecation = true;

var args = process.argv.splice(2); //接收控制台的参数
var mode = "dev";
var prjName = "";
args.forEach(function(value, index, array) {
  if (value.indexOf("env=") > -1) {
    mode = value.substr(value.indexOf("=") + 1);
  } else if (value.indexOf("context=") > -1) {
    prjName = value.substr(value.indexOf("=") + 1);
  }
});

var color = {
  log: ["\x1B[30m", "\x1B[39m"],
  debug: ["\x1B[34m", "\x1B[39m"],
  info: ["\x1B[32m", "\x1B[39m"],
  error: ["\x1B[31m", "\x1B[39m"],
  warn: ["\x1B[33m", "\x1B[39m"]
};

if (!prjName) {
  console.log(color.error[0] + "context参数不能为空!!!" + color.error[1]);
  process.exit();
}

const webpack = require("webpack"),
  path = require("path"),
  // ip = require("ip").address(),
  ip = "localhost",
  CopyWebpackPlugin = require("copy-webpack-plugin"),
  CleanWebpackPlugin = require("clean-webpack-plugin"),
  HtmlWebpackPlugin = require("html-webpack-plugin"), // 入口首页生成插件
  ExtractTextPlugin = require("extract-text-webpack-plugin"),
  os = require("os"),
  HappyPack = require("happypack"),
  happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }),
  ParallelUglifyPlugin = require("webpack-parallel-uglify-plugin"),
  WebpackSftpClient = require("webpack-sftp-client"),
  AutoDllPlugin = require("autodll-webpack-plugin");

const urlSwitch = require("./prjUrl");

var urlConfig = urlSwitch[prjName];

const vendorBase = ["vue/dist/vue.esm.js", "vuex", "vue-router", "element-ui"];
const vendorConfig = {
  ultron: vendorBase.concat(["jquery"]),
  "ultron-ops": vendorBase.concat(["jquery"]),
  template: vendorBase.concat(["jquery"]),
  collection: vendorBase.concat(["vue-area-linkage", "echarts", "moment"]),
  manual: vendorBase.concat(["echarts", "moment"]),
  xmagic: vendorBase.concat(["echarts", "moment", "v-tooltip", "sortablejs", "jquery"]),
  xmagic_monitor: vendorBase.concat(["echarts", "moment", "v-tooltip", "vuedraggable"]),
  xraise: vendorBase.concat(["echarts", "moment", "v-tooltip", "sortablejs"]),
  xraise_out: vendorBase.concat(["echarts", "moment", "v-tooltip", "sortablejs"]),
  xraise_monitor: vendorBase.concat(["echarts", "moment", "v-tooltip"])
};

const globBase = {
  "process.env": {
    NODE_ENV: mode == "dev" ? '"development"' : '"production"'
  },
  __CONFIGMODE__: JSON.stringify(mode),
  __DOMAIN__: JSON.stringify(mode == "dev" ? "/test" : urlConfig[mode].url),
  __UPLOAD_URL__: JSON.stringify(urlConfig[mode].url) //文件上传域名
};

const globBaseConfig = {
  ultron: globBase,
  "ultron-ops": globBase,
  template: globBase,
  collection: Object.assign({}, globBase, {
    __SITE_ID__: JSON.stringify(urlConfig[mode].siteID)
  }),
  manual: globBase,
  xmagic: globBase,
  xmagic_monitor: globBase,
  xraise: Object.assign({}, globBase, { __RUN_MODE__: JSON.stringify(mode) }),
  xraise_out: Object.assign({}, globBase, {
    __RUN_MODE__: JSON.stringify(mode)
  }),
  xraise_monitor: Object.assign({}, globBase, {
    __RUN_MODE__: JSON.stringify(mode)
  })
};

const jsDirBase = [
  path.resolve(__dirname, prjName + "/src/directive"),
  path.resolve(__dirname, prjName + "/src/filter"),
  path.resolve(__dirname, prjName + "/src/routers"),
  path.resolve(__dirname, prjName + "/src/store"),
  path.resolve(__dirname, prjName + "/src/utils"),
  path.resolve(__dirname, prjName + "/src/app.js")
];

const jsDirBaseConfig = {
  ultron: jsDirBase,
  "ultron-ops": jsDirBase,
  template: jsDirBase,
  collection: jsDirBase.concat([path.resolve(__dirname, prjName + "/src/container"), path.resolve(__dirname, prjName + "/src/mixins")]),
  manual: jsDirBase.concat([path.resolve(__dirname, prjName + "/src/mixins")]),
  xmagic: jsDirBase.concat([path.resolve(__dirname, prjName + "/src/static/blockly/custom"), path.resolve(__dirname, prjName + "/src/vendors"), path.resolve(__dirname, prjName + "/src/mixins")]),
  xmagic_monitor: jsDirBase.concat([path.resolve(__dirname, prjName + "/src/vendors"), path.resolve(__dirname, prjName + "/src/mixins")]),
  xraise: jsDirBase.concat([path.resolve(__dirname, prjName + "/src/vendors"), path.resolve(__dirname, prjName + "/src/mixins")]),
  xraise_out: jsDirBase.concat([path.resolve(__dirname, prjName + "/src/vendors"), path.resolve(__dirname, prjName + "/src/mixins")]),
  xraise_monitor: jsDirBase.concat([path.resolve(__dirname, prjName + "/src/vendors"), path.resolve(__dirname, prjName + "/src/mixins")])
};

var prdPluginBase = [
  new CleanWebpackPlugin([path.resolve(__dirname, prjName + "/build/*")]),
  new webpack.optimize.CommonsChunkPlugin({
    // The order of this array matters
    names: ["common"],
    minChunks: 2
  }),
  new ExtractTextPlugin({
    filename: "css/[name].[chunkhash:5].css",
    allChunks: true
  }),
  // 产生更大体积的bundle,减少客户端请求
  new webpack.optimize.AggressiveMergingPlugin()
];

// 本地项目名ultron-ops,显示项目名是ultron_ops,所以要将-替换成_
const prjPath = prjName.replace(/-/g, "_");

// if (mode == "test" || mode == "dev_test") {
//   prdPluginBase = prdPluginBase.concat([
//     new WebpackSftpClient({
//       port: "22",
//       host: "10.253.14.94",
//       username: "wangpenghui",
//       password: "PQQrT3l8sZmBehr2",
//       path: path.resolve(__dirname, prjName + "/build"),
//       remotePath: mode == "dev_test" ? "/sz/" + prjPath + "_dev/" : "/sz/" + prjPath + "/",
//       verbose: true //控制台显示详细信息
//     })
//   ]);
// } else if (mode == "uat") {
//   prdPluginBase = prdPluginBase.concat([
//     new WebpackSftpClient({
//       port: "22",
//       host: "10.253.9.215",
//       username: "peach",
//       password: "peach!@#ZA",
//       path: path.resolve(__dirname, prjName + "/build"),
//       remotePath: "/alidata1/sftp/peach/szapp-uat.zhonganonline.com/" + prjPath + "/",
//       verbose: true //控制台显示详细信息
//     })
//   ]);
// } else if (mode == "prd") {
//   prdPluginBase = prdPluginBase.concat([
//     new WebpackSftpClient({
//       port: "80",
//       host: "100.112.34.113",
//       username: "peach",
//       password: "peach!@#ZA",
//       path: path.resolve(__dirname, prjName + "/build"),
//       remotePath: "/alidata1/sftp/peach/szapp.zhonganonline.com/" + prjPath + "/",
//       verbose: true //控制台显示详细信息
//     })
//   ]);
// }

const prdPluginConfig = {
  ultron: prdPluginBase,
  "ultron-ops": prdPluginBase,
  template: prdPluginBase.concat([
    new CopyWebpackPlugin([
      // 复制插件
      {
        from: path.join(__dirname, prjName + "/src/static/js"),
        to: path.join(__dirname, prjName + "/build/static/js")
      }
    ])
  ]),
  collection: prdPluginBase,
  manual: prdPluginBase,
  xmagic_monitor: prdPluginBase,
  xmagic: prdPluginBase.concat([
    new CopyWebpackPlugin([
      // 复制插件
      {
        from: path.join(__dirname, prjName + "/src/static/blockly"),
        to: path.join(__dirname, prjName + "/build/static/blockly")
      },
      {
        from: path.join(__dirname, prjName + "/src/static/g6Editor"),
        to: path.join(__dirname, prjName + "/build/static/g6Editor")
      },
      // { from: path.join(__dirname, prjName + '/src/static/aceEdit'),   to: path.join(__dirname, prjName + '/build/static/aceEdit') },
      {
        from: path.join(__dirname, prjName + "/src/static/rightMenu"),
        to: path.join(__dirname, prjName + "/build/static/rightMenu")
      },
      {
        from: path.join(__dirname, prjName + "/src/downLoadFile"),
        to: path.join(__dirname, prjName + "/build/downLoadFile")
      }
    ])
  ]),
  xraise: prdPluginBase.concat([
    new CopyWebpackPlugin([
      // 复制插件
      {
        from: path.join(__dirname, prjName + "/src/downLoadFile"),
        to: path.join(__dirname, prjName + "/build/downLoadFile")
      }
    ])
  ]),
  xraise_monitor: prdPluginBase,
  xraise_out: prdPluginBase.concat([
    new CopyWebpackPlugin([
      // 复制插件
      {
        from: path.join(__dirname, prjName + "/src/downLoadFile"),
        to: path.join(__dirname, prjName + "/build/downLoadFile")
      }
    ])
  ])
};

if (!urlConfig) {
  console.log(color.error[0] + "没有匹配的项目!!!" + color.error[1]);
  process.exit();
}

console.log(color.info[0] + "\n当前运行项目:%s\t环境:%s\n" + color.info[1], prjName, urlConfig[mode].text);

let ParallelUglify = [
  new ParallelUglifyPlugin({
    // 缓存压缩后的结果，下次遇到一样的输入时直接从缓存中获取压缩后的结果返回
    cacheDir: ".dll-cache/" + prjName,
    workers: os.cpus().length,
    mangle: true,
    // 传递给 UglifyES 的参数
    uglifyES: {
      output: {
        // 最紧凑的输出
        beautify: false,
        // 删除所有的注释
        comments: false
      },
      compress: {
        // 在UglifyJs删除没有用到的代码时不输出警告
        warnings: false,
        // 删除所有的 `console` 语句，可以兼容ie浏览器
        drop_console: mode == "dev" ? false : true,
        // 内嵌定义了但是只用到一次的变量
        collapse_vars: true,
        // 提取出出现多次但是没有定义成变量去引用的静态值
        reduce_vars: true
      }
    }
  })
];

var publicPath = mode === "dev" ? "/" : "./assets/";
const publicPlugin = [
  new webpack.ProvidePlugin({
    $: "jquery",
    jQuery: "jquery"
  }),
  new HtmlWebpackPlugin({
    favicon: mode === "dev" ? path.resolve(__dirname, prjName + "/src/static/imgs/favicon.ico") : "./src/static/imgs/favicon.ico",
    template: mode === "dev" ? path.resolve(__dirname, prjName + "/src/index.html") : "./src/index.html",
    filename: mode === "dev" ? "index.html" : "../index.html",
    inject: "body",
    hash: true,
    cache: true
    // minify: {
    //     removeComments: true,
    //     collapseWhitespace: true,
    //     removeRedundantAttributes: true,
    //     useShortDoctype: true,
    //     removeEmptyAttributes: true,
    //     removeStyleLinkTypeAttributes: true,
    //     keepClosingSlash: true,
    //     minifyJS: true,
    //     minifyCSS: true,
    //     minifyURLs: true
    // }
  }),
  new AutoDllPlugin({
    inject: true, // will inject the DLL bundles to html
    // context: path.join(__dirname, '..'),
    filename: "[name]_[chunkhash].dll.js",
    plugins: mode !== "dev" ? ParallelUglify : [],
    entry: {
      vendor: vendorConfig[prjName]
    }
  }),
  new webpack.DefinePlugin(globBaseConfig[prjName]),

  // UglifyJsPlugin 将不再把所有 loader 都切到代码压缩模式
  new webpack.LoaderOptionsPlugin({
    debug: false,
    // options: {
    //     postcss: [
    //         require('autoprefixer')
    //     ],
    //     scss: ['vue-style-loader', 'css', 'sass'].join('!')
    // },
    vue: {
      // use custom postcss plugins
      loaders: {
        scss: ["vue-style-loader", "css-loader", "sass-loader"]
      },
      postcss: [
        require("postcss-flexbugs-fixes")(),
        require("autoprefixer")({
          browsers: [">1%", "last 4 versions", "Firefox ESR", "not ie < 9"]
        })
      ]
    }
  }),
  new HappyPack({
    id: "babel-loader",
    threadPool: happyThreadPool,
    loaders: [
      {
        loader: "babel-loader",
        options: { babelrc: true, cacheDirectory: false }
      }
    ]
  }),

  new HappyPack({
    id: "vue-loader",
    threadPool: happyThreadPool,
    loaders: ["vue-loader"]
  }),

  new HappyPack({
    id: "scss-loader",
    threadPool: happyThreadPool,
    loaders: ["style-loader", "css-loader", "sass-loader"]
  })
];

var entryApp = [path.resolve(__dirname, prjName + "/src/app.js")]; //入口文件
var output = {
  path: path.resolve(__dirname, prjName + "/build/assets"),
  publicPath: publicPath,
  filename: "[name].[chunkhash].js"
};
if (mode == "dev") {
  entryApp = entryApp.concat([
    // 给webpack-dev-server启动一个本地服务，并连接到8080端口
    `webpack-dev-server/client?http://${ip}:${urlConfig.port}`,
    // 给上面启动的本地服务开启自动刷新功能，'only-dev-server'的'only-'意思是只有当模块允许被热更新之后才有热加载，否则就是整页刷新
    "webpack/hot/only-dev-server"
  ]);
  output["filename"] = "[name].js";
}
module.exports = {
  entry: {
    app: entryApp
  },
  output: output,
  devServer: {
    port: urlConfig.port,
    host: ip,
    contentBase: path.resolve(__dirname, prjName + "/src"),
    // hot: true,
    inline: true,
    open: true,
    historyApiFallback: true,
    disableHostCheck: true, //解决invalid host header
    /*开发模式代理相应Ajax请求到指定服务器*/
    proxy: {
      "/test/*": {
        //测试环境--域名
        target: urlConfig.dev.url,
        changeOrigin: true,
        logLevel: "debug",
        pathRewrite: { "^/test": "" }
      }
    },
    publicPath: publicPath,
    noInfo: false
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: "happypack/loader?id=vue-loader",
        include: [path.resolve(__dirname, prjName + "/src/container/"), path.resolve(__dirname, prjName + "/src/components/"), path.resolve(__dirname, "node_modules/vue-touch-ripple/src/")]
      },
      {
        test: /\.js$/,
        loader: "babel-loader",
        loader: "happypack/loader?id=babel-loader",

        // 对于include，更精确指定要处理的目录，这可以减少不必要的遍历，从而减少性能损失。
        // 同样，对于已经明确知道的，不需要处理的目录，则应该予以排除，从而进一步提升性能。
        // 假设你有一个第三方组件的引用，它肯定位于node_modules，通常它将有一个 src 和一个 dist 目录。
        // 如果配置 Webpack 来排除 node_modules，那么它将从 dist 已经编译的目录中获取文件。否则会再次编译它们。
        include: jsDirBaseConfig[prjName],
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        loader:
          mode === "dev"
            ? ["style-loader", "css-loader"]
            : ExtractTextPlugin.extract({
                use: [
                  {
                    loader: "style-loader",
                    loader: "css-loader"
                  }
                ]
              })
      },
      {
        test: /\.scss$/,
        //loaders的处理顺序是从右到左的，这里就是先运行css-loader然后是style-loader
        loaders: ["style-loader", "css-loader", "sass-loader"]
      },
      {
        //当我们需要读取json格式文件时，我们不再需要安装任何loader，webpack2中将会内置 json-loader，自动支持json格式的读取（喜大普奔啊）。
        test: /\.json$/, //获取json数据的loader
        loader: "json-loader"
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: "url-loader",
        query: {
          // 当图片大小小于这个限制的时候，会自动启用base64编码图片。减少http请求,提高性能
          limit: 100000,
          name: "img/[name].[hash:7].[ext]"
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: "url-loader",
        query: {
          limit: 10000,
          name: "fonts/[name].[hash:7].[ext]"
        }
      }
    ]
  },
  resolve: {
    //注意一下, extensions webpack2第一个不是空字符串! 对应不需要后缀的情况.
    extensions: [".js", ".json", ".sass", ".scss", ".less", "jsx", ".vue"],
    //模块别名定义，方便后续直接引用别名，无须多写长长的地址
    alias: {
      vue$: "vue/dist/vue.esm.js",
      src: path.resolve(__dirname, prjName + "/src"),
      assets: path.resolve(__dirname, prjName + "/build/assets"),
      components: path.resolve(__dirname, prjName + "/src/components")
    }
    // 配置了这个属性之后 vue 和 vue-router这些第三方的包都不会被构建进 js 中，那么我们就需要通过 cdn 进行文件的引用了
    //externals对象的key是给require时用的，比如require('vue'),，对象的value表示的是如何在global（即window）中访问到该对象，这里是window.Vue
    /*  externals: {
                  'vue': 'Vue',
                  'vue-router': 'VueRouter'
              },*/
  },
  devtool: mode === "dev" ? "cheap-module-source-map" : undefined,
  // vue: {
  //     loaders: {
  //         scss: ['vue-style-loader', 'css', 'sass'].join('!')
  //     },
  //     postcss: [
  //         require('postcss-flexbugs-fixes')(),
  //         require('autoprefixer')({
  //             browsers: [
  //                 ">1%",
  //                 "last 4 versions",
  //                 "Firefox ESR",
  //                 "not ie < 9"
  //             ]
  //         })
  //     ]
  // },
  plugins:
    mode === "dev"
      ? [
          // new HtmlWebpackPlugin({
          //  template: prjName+'/src/index.html' // 模版文件
          // }),
          // new DllReferencePlugin({
          //     manifest: require('./src/dll/vendor.manifest.json')
          //   }),
          new webpack.HotModuleReplacementPlugin()
        ].concat(publicPlugin)
      : publicPlugin.concat(prdPluginConfig[prjName])
};
